using System;
using System.Collections.Generic;
using System.Linq;

namespace VisionarySystems.TimeRegi.Model.TimePeriods
{
	public class WorkDay : TimePeriodHost<int>, ITimePeriode
	{
		#region Private members

		DateTime m_WorkDate;

		#endregion

		#region Ctor

		public WorkDay(DateTime WorkDate)
		{
			m_WorkDate = WorkDate.Date;
			if (m_WorkDate == null)
				throw new ArgumentOutOfRangeException("WorkDate must not be null");
			ID = new TimePeriodeID(GetUniqueIndex(), TimePeriodeType.Workday);

		}

		#endregion

		#region properties

		public DateTime WorkDate { get { return m_WorkDate; } }

		public int Year
		{
			get { return m_WorkDate.Year; }
		}


		#endregion

		#region Public Methods

		public static string GetDate(DateTime d)
		{
			return string.Format("{0:D2}/{1:D2}", d.Day, d.Month);
		}

		public override string ToString()
		{
			return string.Format("{0} ({1})", GetDate(m_WorkDate), GetHours(WorkedTime));
		}

		public TimeSpan BrakeTime { get; set; }

		public void Add(IEnumerable<TimeSlot> TimeSlots)
		{
			foreach (TimeSlot slot in TimeSlots)
			{
				m_TimePeriods.Remove(slot.Idx);
				//slot.ID = GetNextID(slot);
				m_TimePeriods.Add(slot.Idx, slot);
			}
		}

		/// <summary>
		/// Assambles all timeslots to one timeslot, where th first start is the start
		/// And the last stop is the stop
		/// It will reuse the first Idx for the new TimeSlot
		/// </summary>
		/// <param name="NewTimeSlots"></param>
		/// <param name="RemovedIndexes">Returns a list of all the indexes of the timeslots that has been removed</param>
		public override bool AssembleTimeslots(out List<TimeSlot> NewTimeSlots, out List<int> RemovedIndexes)
		{
			//Init
			bool result = false;
			try
			{
				RemovedIndexes = new List<int>();
				NewTimeSlots = new List<TimeSlot>();
				if (m_TimePeriods.Count <= 1)
					return result;
				DateTime start = DateTime.MaxValue;
				DateTime stop = DateTime.MinValue;
				//Find Min / Max Values
				foreach (TimeSlot slot in m_TimePeriods.Values)
				{
					RemovedIndexes.Add(slot.Idx);
					if (slot.Start < start)
						start = slot.Start;
					if (slot.Stop > stop)
						stop = slot.Stop;
				}
				//Remove old slots
				Clear();
				// Add the new slot
				TimeSlot newTimeSlot = new TimeSlot(RemovedIndexes[0], start, stop, TimeSlotTypes.WorkTime);
				NewTimeSlots.Add(newTimeSlot);
				Add(newTimeSlot.Idx, newTimeSlot);
				result = true;
			}
			finally
			{ }
			return result;
		}

		private void Clear()
		{
			m_TimePeriods.Clear();
		}
		/*public void Add (TimeSlot NewSlot)
		{
			if (NewSlot.Start.Date == m_WorkDate)
				m_TimeSlots.Add(NewSlot.Start, NewSlot);
			else
				throw new ArgumentOutOfRangeException (string.Format ("StartDate must be the same as the work date: StartTime = {0}, WorkDate = {1}", NewSlot.Start, m_WorkDate.Date));
		}*/

		public IEnumerable<TimeSlot> TimeSlots()
		{
			foreach (ITimePeriode periode in m_TimePeriods.Values)
				yield return periode as TimeSlot;
		}

		public void GetTimePeriode(DateTime StartTime, DateTime EndTime, ref ITimePeriode TimePeriod)
		{
			foreach (var slot in m_TimePeriods.Values)
				slot.GetTimePeriode(StartTime, EndTime, ref TimePeriod);
		}

		public void GetWorkingDates(ref List<DateTime> WorkingDates)
		{
			WorkingDates.Add(m_WorkDate.Date);
		}

		public bool DeleteTimeslots(ref List<int> RemovedIndexes)
		{
			RemovedIndexes.AddRange(from TimeSlot slots in m_TimePeriods.Values select slots.Idx);
			Clear();
			return true;
		}

		public void DeleteTimePeriode(ITimePeriode Periode)
		{
			TimeSlot deleteSlot = Periode as TimeSlot;
			if (deleteSlot != null)
			{
				if (m_TimePeriods.ContainsKey(deleteSlot.Idx))
					m_TimePeriods.Remove(deleteSlot.Idx);
			}
		}

		public void DeleteTimeSlot(int Idx)
		{
			m_TimePeriods.Remove(Idx);
		}

		#endregion
	}
}